#include "Gameboard.h"
#include<vector>


//       TO USE AI JUST CALL move(Gameboard) FUNCTION

class Stack
{
	public:
	Gameboard current_board;
	int max_value_node;
	int min_value_node;
	vector<Gameboard> leafs;
	char current_player;
	Stack()
	{
	current_board.setup();
	max_value_node=0;
	min_value_node=0;
	}
};



class AI
{	char color;
	int depth;
	int best_node;
	vector<Stack> nodes;
	Stack current_state;
	
	void evaluator();// evaluator shell	
	void find_children1();// finds all the moves the AI can make and stores them as nodes without setting the max, min and value for each node
	void find_children2();// finds all the subsequent moves the player can make and stores them as leafs
	int number_moves(char board[10][10]);// returns the number of moves on the characte array;
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	void find_node_values(); //sets the max/min value for each node based on max/min number of moves for each leaf case
							//(min value=minimum number of moves ai can make after humans next move)
							//therefore goal is to maximize the min value
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////							

	void find_best_node();// finds the node with the maximum min value	
	
	public:
	
		Gameboard move(Gameboard b)// gets the board from the engine
		{
			current_state.current_board=b;
			color=b.currentColor();
			
			depth=1;
			evaluator();
			return (nodes[best_node].current_board);
		}
		
		AI()
		{
			depth=0;
			best_node=-1;
		}
	
};
	
void AI:: evaluator()
{
	if (depth==1)
	{
		find_children1();
		depth++;
	}
	if (depth==2)
	{
		find_children2();
		find_node_values();
		depth++;
	}
	find_best_node();
}
	
void AI:: find_children1()
{
char op;
if (color=='@')
{
	op='O';
}
else
{
 op='@';
}
for(int i=0; i<10; i++)
	{
		for(int j=0; j<10; j++)
		{
			if(current_state.current_board.board[i][j]=='*')
			{
			nodes.push_back(current_state);
			nodes[nodes.size()-1].current_board.Setpiece(color);
			nodes[nodes.size()-1].current_board.showNextPos();
			nodes[nodes.size()-1].current_board.move(i,j);
			
			nodes[nodes.size()-1].current_player=op;
			}
		}
	}
	

}
void AI:: find_children2()
{
	for(int p=0; p<nodes.size(); p++)
	{
		for(int i=0; i<10; i++)
		{
			for(int j=0; j<10; j++)
			{
				if(nodes[p].current_board.board[i][j]=='*');
				{	
					nodes[p].leafs.push_back(nodes[p].current_board);
					nodes[p].leafs[nodes[p].leafs.size()-1].Setpiece(nodes[p].current_player);
					nodes[p].leafs[nodes[p].leafs.size()-1].showNextPos();
					nodes[p].leafs[nodes[p].leafs.size()-1].move(i,j);
				}
			}
		}
	}
}
void AI::find_node_values()
{
	int a,min=-1,max=100;
	for(int p=0; p<nodes.size(); p++)
	{
		for(int t=0; t<nodes.size(); t++)
		{
		a=number_moves(nodes[p].leafs[t].board);
		if(max<a)
		max=a;
		if(min>a)
		min=a;
		}
		nodes[p].max_value_node=max;
		nodes[p].min_value_node=min;
		
	}
	
}

int AI:: number_moves(char board[10][10])
{
	int c=0;
	for(int i=0; i<10; i++)
	{
		for(int j=0; j<10; j++)
		{
		if(board[i][j]=='*')
		c++;
		}
	}
	return c;
}

void AI::find_best_node()
{
int a,max=-1;
for(int p=0; p<nodes.size(); p++)
	{
		a=nodes[p].min_value_node;
		if(max<a)
		{
			max=a;
			best_node=p;
		}
	}
}
